#include "stdafx.h"
#include "KeyBoardHookImp.h"

#pragma data_seg(".FantasyYS")

HWND g_hWndCaller = NULL;
HHOOK g_hHook = NULL;

#pragma data_seg() 

#pragma comment(linker,"/SECTION:.FantasyYS,RWS") 

extern HINSTANCE g_Hinstance;

CKeyBoardHookImp::CKeyBoardHookImp()
{
	
}

CKeyBoardHookImp::~CKeyBoardHookImp()
{
	
}

HRESULT STDMETHODCALLTYPE CKeyBoardHookImp::InstallHook(HWND hWnd)
{
	HRESULT hRet = E_FAIL;
	if (::IsWindow(hWnd))
	{
		g_hWndCaller = hWnd;
		//HINSTANCE hInstance = ::GetModuleHandle(_T("KeyboardHookDll.dll"));
		g_hHook = ::SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc, g_Hinstance, 0);
		
		if (g_hHook)
		{
			hRet = S_OK;
			::OutputDebugString(_T("InstallHook Success\r\n"));
		}
		else
		{
			::OutputDebugString(_T("InstallHook Failure\r\n"));
		}
	}
	return hRet;

}

HRESULT STDMETHODCALLTYPE CKeyBoardHookImp::UninstallHook()
{
	HRESULT hRet = E_FAIL;
	if (g_hHook)
	{
		if (::UnhookWindowsHookEx(g_hHook))
		{
			g_hHook = NULL;
			hRet = S_OK;
			::OutputDebugString(_T("UninstallHook Success\r\n"));
		}
		else
		{
			::OutputDebugString(_T("UninstallHook Failure\r\n"));
		}
	}
	return hRet;
}

LRESULT CALLBACK CKeyBoardHookImp::KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	
	if (HC_ACTION == nCode && (lParam & 0x80000000))
	{
		COPYDATASTRUCT copyData;
		KeyBoardMsg msg;
		msg.processId = ::GetCurrentProcessId();
		msg.threadId = ::GetCurrentThreadId();
		::GetModuleFileName(NULL, msg.szBuffer, MAX_PATH);
		msg.vkCode = wParam;

		copyData.dwData =0;
		copyData.cbData = sizeof(msg);
		copyData.lpData = &msg;

		::SendMessage(g_hWndCaller, WM_COPYDATA, NULL, (LPARAM)&copyData);
	}

	return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);
}	

HRESULT WINAPI CreateKeyBoardHook( REFIID riid, void** ppvObj )
{
	if (__uuidof(IKeyBoardHook) == riid || IID_IUnknown == riid)
	{
		IKeyBoardHook* pIXxx = new ComObject<CKeyBoardHookImp>;
		if (NULL == pIXxx)
			return E_OUTOFMEMORY;

		pIXxx->AddRef();

		*ppvObj = pIXxx;

		return S_OK;
	}

	return S_FALSE;
}

